#include <iostream>
#include <deque>
#include <list>
#include <vector>
#include <string>
using namespace std;

///////////////////////////////////////////////////////////////////////////////////////////类型模板参数///////////////////////////////////////////////////////////////////////////////////////////

template <typename... Types> class MyVaridic {
  public:
    MyVaridic() {
        cout << "MyVaridic::MyVaridic()泛化版本执行了 this=" << this << endl;
    }
};
template <typename Head, typename... Tail>
class MyVaridic<Head, Tail...> : private MyVaridic<Tail...> {
  public:
    MyVaridic() : mHead() {
        cout << "MyVaridic::MyVaridic() 无参偏特化化版本执行了 this=" << this
             << "\t sizeof...(Tail)" << sizeof...(Tail) <<"\ttypeid()="<<typeid(Head).name()<< endl;
    }
    MyVaridic(Head h, Tail... tail) : mHead(h), MyVaridic<Tail...>(tail...) {
        cout << "MyVaridic::MyVaridic() 有参偏特化化版本执行了 this=" << this
             << "\t sizeof...(Tail)" << sizeof...(Tail) << endl;
    }

  private:
    Head mHead;
};
template <> class MyVaridic<> {
  public:
    MyVaridic() {
        cout << "MyVaridic::MyVaridic()全特化版本执行了 this=" << this << endl;
    }
};

///////////////////////////////////////////////////////////////////////////////////////////无类型模板参数///////////////////////////////////////////////////////////////////////////////////////////
template <int... Types> class MyVaridic1 {
  public:
    MyVaridic1() {
        cout << "MyVaridic1::MyVaridic1()泛化版本执行了 this=" << this << endl;
    }
};
template <int Head, int... Tail>
class MyVaridic1<Head, Tail...> : private MyVaridic1<Tail...> {
  public:
    MyVaridic1() {
        cout << "MyVaridic1::MyVaridic1() 无参偏特化化版本执行了 this=" << this
             << "\t sizeof...(Tail)" << sizeof...(Tail) << "\t head=" << Head
             << endl;
    }
};
template <> class MyVaridic1<> {
  public:
    MyVaridic1() {
        cout << "MyVaridic1::MyVaridic1()全特化版本执行了 this=" << this
             << endl;
    }
};
///////////////////////////////////////////////////////////////////////////////////////////模板模板参数///////////////////////////////////////////////////////////////////////////////////////////
template <typename T, template <typename> class... Container> class MyVaridic2 {
  public:
    MyVaridic2() {
        cout << "MyVaridic2::MyVaridic2()泛化版本执行了 this=" << this << "\t sizeof...(Container)" << sizeof...(Container)
             << "\tT is type:" << typeid(T).name() << endl;
    }
};
template <typename T, template <typename> class FirstContainer,
          template <typename> class... Container>
class MyVaridic2<T, FirstContainer, Container...>
    : private MyVaridic2<T, Container...> {
  public:
    MyVaridic2() {
        firstC.push_back(12);
        cout << "MyVaridic2::MyVaridic2() 无参偏特化化版本执行了 this=" << this
             << "\t sizeof...(Container)" << sizeof...(Container) << "\tT is type:" << typeid(T).name() 
             <<"\tfirstContainer cout:"<<firstC.size()<< endl;

        
    }

  private:
    FirstContainer<T> firstC;
};
template <typename T, template <typename> class... Container>
class MyVaridic2Test : private MyVaridic2<T, Container...> {
  public:
    MyVaridic2Test() {
        cout << "MyVaridic2Test::MyVaridic2Test() 无参偏特化化版本执行了 this="
             << this << "\t sizeof...(Container)" << sizeof...(Container)
             << "\tT is type:" << typeid(T).name() << endl;
    }
};

template <typename T> using LV = std::vector<T>;
template <typename T> using LS = std::list<T>;
template <typename T> using LD = std::deque<T>;
void testVaridicTemplate() {

    // 1
    cout << "test1-------------------------------------------" << endl;
    MyVaridic<int, float, string, double> my1;
    MyVaridic<int, float, string, double> my11(1, 2.3, "45", 6.7);
    cout << "test2-------------------------------------------" << endl;
    MyVaridic1<1, 2, 3, 4, 5, 6, 7> my2;

    cout << "test3-------------------------------------------" << endl;

    MyVaridic2Test<int, LV, LS, LD> my3;
}